﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraLayout;
using System.Windows.Forms;
using DevExpress.XtraEditors.Repository;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using DevExpress.XtraGrid.Columns;
namespace UniMana.Utils.LoadData
{
    public static class LoadData
    {

        /// Đổ dữ liệu lên RepositoryItemLookUpEdit
        /// </summary>
        /// <param name="rlu">RepositoryItemLookUpEdit</param>
        /// <param name="table">Bảng dữ liệu</param>
        /// <param name="valueMember">Giá trị cho RepositoryItemLookUpEdit</param>
        /// <param name="displayMember">Giá trị hiển thị trên RepositoryItemLookUpEdit</param>
        /// <returns>RepositoryItemLookUpEdit hiện hành</returns>
        public static LookUpEdit GetData(this LookUpEdit lue, dynamic table, string valueMember = "",
                                                   string displayMember = "Name", bool showHeader = false,
                                                   bool showFooter = false,
                                                   bool chooseAll = false, bool noChoose = false)
        {
            lue.Properties.Columns.Clear();
            //chỉ định datasource cho lookupedit
            if (chooseAll)
            {
                try
                {
                    DataTable dt = (DataTable)table;
                    object[] obj = new object[dt.Columns.Count];
                    obj[0] = 0;
                    for (int i = 1; i < dt.Columns.Count; i++)
                    {
                        if (dt.Columns[i].ColumnName == "Name")
                        {
                            obj[i] = " --Chọn hết-- ";
                        }
                        else
                        {
                            obj[i] = null;
                        }
                    }
                    dt.Rows.Add(obj);
                    lue.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
                }
                catch { }
            }
            if (noChoose)
            {
                try
                {
                    DataTable dt = (DataTable)table;
                    object[] obj = new object[dt.Columns.Count];
                    obj[0] = -1;
                    for (int i = 1; i < dt.Columns.Count; i++)
                    {
                        if (dt.Columns[i].ColumnName == "Name")
                        {
                            obj[i] = " --Không chọn-- ";
                        }
                        else
                        {
                            obj[i] = null;
                        }
                    }
                    dt.Rows.Add(obj);
                    lue.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
                }
                catch { }
            }

            lue.Properties.DataSource = table;

            //setting cho lookupedit
            lue.Properties.ShowHeader = showHeader;
            lue.Properties.ShowFooter = showFooter;
            lue.Properties.NullText = "--Chọn--";

            //Data
            lue.Properties.DisplayMember = displayMember;

            if (valueMember == "")
                valueMember = lue.Name.Replace("lue", "") + "Key";
            lue.Properties.ValueMember = valueMember;

            //tạo cột mới
            LookUpColumnInfoCollection coll = lue.Properties.Columns;
            coll.Add(new LookUpColumnInfo(displayMember, "Tên"));
            if (chooseAll)
            {
                lue.Properties.Columns[displayMember].SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
            }
            if (noChoose)
            {
                lue.Properties.Columns[displayMember].SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
            }

            lue.Properties.SearchMode = SearchMode.AutoComplete;
            lue.Properties.TextEditStyle = TextEditStyles.Standard;

            lue.KeyDown += (sender, e) =>
                {
                    if (e.KeyCode == Keys.Delete)
                    {
                        lue.EditValue = null;
                    }
                };

            return lue;
        }


        /// Ðổ dữ liệu lên GridLookUpEdit
        /// </summary>
        /// <param name="rlu">GridLookUpEdit</param>
        /// <param name="table"></param>
        /// <param name="valueMember">Giá tr? Bảng dữ liệu cho GridLookUpEdit</param>
        /// <param name="displayMember">Giá trị hiển thị trên GridLookUpEdit</param>
        /// <returns>GridLookUpEdit hiện hành</returns>
        public static GridLookUpEdit GetData(this GridLookUpEdit glu, dynamic table, string valueMember = "",
                                                   string displayMember = "Name", bool showHeader = false,
                                                   bool showFooter = false,
                                                   string colCaption ="Tên",
                                                   string colfieldName ="Name",
                                                   bool autoFilter = true,
                                                   bool chooseAll = false, bool noChoose = false)
        {
            //chỉ định datasource cho lookupedit
            if (chooseAll)
            {
                DataTable dt = (DataTable)table;
                dt.Rows.Add(new object[] { 0, " --Chọn hết-- " });
                glu.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
            }
            if (noChoose)
            {
                DataTable dt = (DataTable)table;
                dt.Rows.Add(new object[] { -1, " --Không chọn-- " });
                glu.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
            }

            glu.Properties.DataSource = table;

            //setting cho lookupedit
            glu.Properties.ShowFooter = showFooter;
            glu.Properties.NullText = "--Chọn--";


            //Data
            glu.Properties.DisplayMember = displayMember;

            if (valueMember == "")
                valueMember = glu.Name.Replace("lue", "") + "Key";
            glu.Properties.ValueMember = valueMember;

            //Xóa tấc cả các cột hiện có
            //glu.Properties.View.Columns.Clear();

            //Thêm cột mới.
            //GridColumn col = new GridColumn();
            //col.Caption = colCaption;
            //col.FieldName = displayMember;
            //col.Name = "col1";
            //col.Visible = true;
            //col.VisibleIndex = 0;

            //glu.Properties.View.Columns.AddRange(new DevExpress.XtraGrid.Columns.GridColumn[] {col});
            

            if (chooseAll)
            {
                //lue.Properties.Columns[displayMember].SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
            }
            if (noChoose)
            {
                //lue.Properties.Columns[displayMember].SortOrder = DevExpress.Data.ColumnSortOrder.Ascending;
            }

            glu.Properties.View.OptionsView.ShowAutoFilterRow = autoFilter;
            glu.Properties.BestFitMode = BestFitMode.BestFitResizePopup;
            glu.Properties.TextEditStyle = TextEditStyles.Standard;


            return glu;
        }
     

        /// <summary>
        /// Đổ dữ liệu lên RepositoryItemLookUpEdit  
        /// </summary>
        /// <param name="rlu">RepositoryItemLookUpEdit</param>
        /// <param name="table">Bảng dữ liệu</param>
        /// <param name="valueMember">Giá trị cho RepositoryItemLookUpEdit</param>
        /// <param name="displayMember">Giá trị hiển thị trên RepositoryItemLookUpEdit</param>
        /// <returns>RepositoryItemLookUpEdit hiện hành</returns>
        public static RepositoryItemLookUpEdit GetData(this RepositoryItemLookUpEdit lue, dynamic table, string valueMember = "",
                                                   string displayMember = "Name")
        {
            //chỉ định datasource cho lookupedit
            lue.DataSource = table;

            //setting cho lookupedit
            //lue.Properties.ShowFooter = false;
            lue.NullText = "--Chọn--";

            //Data
            lue.DisplayMember = displayMember;

            if (valueMember == "")
                valueMember = lue.Name.Replace("rlu", "") + "Key";
            lue.ValueMember = valueMember;

            //tạo cột mới
            LookUpColumnInfoCollection coll = lue.Columns;
            coll.Add(new LookUpColumnInfo(displayMember, "Tên"));
            lue.TextEditStyle = TextEditStyles.Standard;

            return lue;
        }
        /// <summary>
        /// Binding dữ liệu lên LayouControl
        /// </summary>
        /// <param name="ctr"></param>
        /// <param name="bdsSource"></param>
        /// <returns></returns>
        public static LayoutControlGroup LoadOneRecord(this LayoutControlGroup ctr, dynamic bdsSource)
        {
            foreach (LayoutControlItem c in ctr.Items)
            {
                if (c.TypeName != "EmptySpaceItem" && c.TypeName != "SimpleButton")
                {
                    try
                    {
                        if (c.Visibility == DevExpress.XtraLayout.Utils.LayoutVisibility.Never)
                        {
                            continue;
                        }
                        string dataMember = "";
                        c.Control.DataBindings.Clear();

                        //control là TextEdit
                        if (c.Control.Name.Contains("txt") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("txt", "");
                            c.Control.DataBindings.Add(new Binding("Text", bdsSource, dataMember, true));
                            continue;
                        }
                        //control là CaclEdit
                        if (c.Control.Name.Contains("cal") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("cal", "");
                            c.Control.DataBindings.Add(new Binding("Value", bdsSource, dataMember, true));
                            continue;
                        }

                        //control là MemoEdit
                        if (c.Control.Name.Contains("mne") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("mne", "");
                            c.Control.DataBindings.Add(new Binding("Text", bdsSource, dataMember, true));
                            continue;
                        }

                        //control lo LookUpEdit
                        if (c.Control.Name.Contains("lue") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("lue", "");
                            c.Control.DataBindings.Add(new Binding("EditValue", bdsSource, dataMember + "Key", true));
                            continue;
                        }

                        //control lo LookUpEdit
                        if (c.Control.Name.Contains("glu") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("glu", "");
                            c.Control.DataBindings.Add(new Binding("EditValue", bdsSource, dataMember + "Key", true));
                            continue;
                        }

                        //control là DateTimeEdit
                        if (c.Control.Name.Contains("dte") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("dte", "");
                            c.Control.DataBindings.Add(new Binding("EditValue", bdsSource, dataMember, true));
                            continue;
                        }

                        //control là CheckboxEdit
                        if (c.Control.Name.Contains("cke") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("cke", "");
                            c.Control.DataBindings.Add(new Binding("Checked", bdsSource, dataMember, true));
                            continue;
                        }

                        //control là PictureEdit 
                        if (c.Control.Name.Contains("pte") && !c.Control.Name.Contains("NB"))
                        {
                            dataMember = c.Control.Name.Replace("pte", "");
                            c.Control.DataBindings.Add(new Binding("Image", bdsSource, dataMember, true));
                            continue;
                        }

                    }
                    catch (Exception e) { MessageBox.Show("Lỗi binding dữ liệu:\n" + e.Message, "System Error"); }
                }
            }
            return ctr;
        }

        /// <summary>
        /// Lưu dữ liệu
        /// </summary>
        /// <param name="frm"></param>
        /// <param name="bdSoure"></param>
        /// <param name="db"></param>
        /// <param name="showDig"></param>
        /// <returns></returns>
        public static bool SaveAll(BindingSource bdSoure, dynamic db, bool showDig = true)
        {
            //frm.Validate();
            try
            {
                bdSoure.EndEdit();
                db.SubmitChanges();
                if (showDig)
                    MessageBox.Show("Lưu dữ liệu thành công", "Lưu", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return true;
            }
            catch
            {
                if (showDig)
                    MessageBox.Show("Lưu thất bại!!!\nSự cố cúp điện hoặc mạng bị đứt hoặc dữ liệu (nhập hoặc dán) vào có thể vượt quá số ký tự cho phép nhập vào ô,\n hoặc có thể một vài ô nhập liệu bắt buộc không được rỗng mà bạn lại chưa nhập... \n vui lòng kiểm tra cho thích hợp rồi lưu lại", "Thông báo lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
        }

        /// <summary>
        /// Lưu dữ liệu
        /// </summary>
        /// <param name="frm"></param>
        /// <param name="bdSoure"></param>
        /// <param name="db"></param>
        /// <param name="showDig"></param>
        /// <returns></returns>
        public static bool Save(this XtraForm frm, BindingSource bdSoure, dynamic db, bool showDig = true)
        {
            frm.Validate();
            try
            {
                bdSoure.EndEdit();
                db.SubmitChanges();
                if (showDig)
                    MessageBox.Show("Lưu dữ liệu thành công", "Lưu", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return true;
            }
            catch
            {
                if (showDig)
                    MessageBox.Show("Lưu thất bại!!!\nSự cố cúp điện hoặc mạng bị đứt hoặc dữ liệu (nhập hoặc dán) vào có thể vượt quá số ký tự cho phép nhập vào ô,\n hoặc có thể một vài ô nhập liệu bắt buộc không được rỗng mà bạn lại chưa nhập... \n vui lòng kiểm tra cho thích hợp rồi lưu lại", "Thông báo lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
        }

        /// <summary>
        /// Chuyển IQueryable sang DataTable 
        /// </summary>
        /// <param name="source">IQueryable nguồn</param>
        /// <returns></returns>
        public static DataTable ToDataTable(this IQueryable varlist)
        {
            DataTable dtReturn = new DataTable();
            PropertyInfo[] oProps = null;
            //IEnumerable<dynamic> varlist = ((IQueryable < dynamic >)source).AsEnumerable();
            if (varlist == null) return dtReturn;

            foreach (var rec in varlist)
            {
                // Use reflection to get property names, to create table, Only first time, others will follow 
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();
                    foreach (PropertyInfo pi in oProps)
                    {
                        Type colType = pi.PropertyType;

                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                        == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }
                DataRow dr = dtReturn.NewRow();

                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                    (rec, null);
                }

                dtReturn.Rows.Add(dr);
            }
            return dtReturn;
        }

        /// <summary>
        /// Chuyển đổi dữ liệu sang Int
        /// </summary>
        /// <param name="obj">Đối tượng chuyển đổi</param>
        /// <returns>Kiểu dữ liệu chuyển sang kiểu int</returns>
        public static int ToInt(this object obj)
        {
            try
            {
                return Convert.ToInt16(obj.ToString());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// Chuyển đổi dữ liệu sang DateTime
        /// </summary>
        /// <param name="obj">Dữ liệu muốn chuyển đổi</param>
        /// <returns>Kiểm datetime, nếu không chuyển được đưa về 00/00/00</returns>
        public static DateTime ToDateTime(this object obj)
        {
            try
            {
                return Convert.ToDateTime(obj.ToString());
            }
            catch
            {
                return new DateTime();
            }
        }

        /// <summary>
        /// Chuyển đổi kiểu dữ liệu sang Guid
        /// </summary>
        /// <param name="obj">Dữ liệu muốn chuyển đổi</param>
        /// <returns>Kiểu Guid</returns>
        public static Guid ToGuid(this object obj)
        {
            try
            {
                return Guid.Parse(obj.ToString());
            }
            catch
            {
                return Guid.Parse(UniMana.Utils.Config.DefaultConfig.EMPTY_GUID);
            }
        }

        /// <summary>
        /// Chuyển đổi kiệu dữ liệu sang Double
        /// </summary>
        /// <param name="obj">Dữ liệu muốn chuyển</param>
        /// <returns>Kiểu dữ liệu dạng double</returns>
        public static double ToDouble(this object obj)
        {
            try
            {
                return Convert.ToDouble(obj.ToString());
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// Làm tròn kiểu dữ liệu double
        /// </summary>
        /// <param name="_number">Số muốn làm tròn</param>
        /// <param name="_decimal">Số thập phân</param>
        /// <returns>Số được làm tròn</returns>
        public static double Round(this double _number,int _decimal = 0)
        {
            try
            {
                return Math.Round(_number, _decimal, MidpointRounding.AwayFromZero);
            }
            catch
            {
                return _number;
            }
        }
        /// <summary>
        /// Làm tròn dữ liệu kiểu float
        /// </summary>
        /// <param name="_number">Số muốn làm tròn</param>
        /// <param name="_decimal">Số thập phân</param>
        /// <returns>Số được làm tròn</returns>
        public static float Round(this float _number, int _decimal = 0)
        {
            try
            {
                return (float)Math.Round((float)_number, _decimal, MidpointRounding.AwayFromZero);
            }
            catch
            {
                return _number;
            }
        }
        /// <summary>
        /// Xep thu tu table
        /// </summary>
        /// <param name="table"> bang truyen vao </param>
        /// <param name="colum"> cot muon sap xep </param>
        /// <param name="asc"> kieu sap xep </param>
        /// <returns></returns>
        public static DataTable SortDataTable(this DataTable table, string colum, bool asc = true)
        {
            try
            {
                DataView dv = table.DefaultView;
                if (asc)
                {                    
                    dv.Sort = colum + " ASC";
                }
                else
                {
                    dv.Sort = colum + " DES";
                }
                return dv.Table;
            }
            catch
            {
                return table;
            }
        }
    }
}
